<template>
  <el-dialog
    v-model="visible"
    :class="props.baseDialog"
    :title="title"
    :width="width"
    :top="top"
    :fullscreen="fullscreen"
    :modal="modal"
    :modal-class="modalClass"
    :append-to-body="appendToBody"
    :lock-scroll="lockScroll"
    :custom-class="['base-dialog', size, customClass]"
    :close-on-click-modal="closeOnClickModal"
    :close-on-press-escape="closeOnPressEscape"
    :show-close="showClose"
    :draggable="draggable"
    :center="center"
    :destroy-on-close="destroyOnClose"
    @open="handleOpen"
    @opened="handleOpened"
    @close="handleClose"
    @closed="handleClosed"
  >
    <!-- 头部插槽 -->
    <template #header="{ close }" v-if="$slots.header">
      <slot name="header" :close="close"></slot>
    </template>

    <!-- 主要内容区域 -->
    <div class="dialog-body" :style="bodyStyle">
      <!-- 内容插槽 -->
      <slot v-if="!loading"></slot>

      <!-- 加载状态 -->
      <div v-else class="loading-container">
        <el-icon class="loading-icon" :size="loadingIconSize">
          <component :is="loadingIcon" />
        </el-icon>
        <span v-if="loadingText" class="loading-text">{{ loadingText }}</span>
      </div>
    </div>

    <!-- 底部插槽 -->
    <template #footer v-if="showFooter">
      <slot name="footer">
        <div class="default-footer">
          <el-button
            v-if="showCancelButton"
            :loading="cancelLoading"
            :disabled="cancelDisabled"
            :size="buttonSize"
            @click="handleCancel"
          >
            {{ cancelButtonText }}
          </el-button>
          <el-button
            type="primary"
            :loading="confirmLoading"
            :disabled="confirmDisabled"
            :size="buttonSize"
            @click="handleConfirm"
          >
            {{ confirmButtonText }}
          </el-button>
        </div>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, watch, computed } from "vue";
import { ElDialog, ElButton, ElIcon } from "element-plus";

const props = defineProps({
  // 控制显示
  modelValue: Boolean,

  // 基础配置
  title: String,
  width: {
    type: String,
    default: "50%",
  },
  size: {
    type: String,
    default: "medium", // small | medium | large
    validator: (val) => ["small", "medium", "large"].includes(val),
  },
  top: {
    type: String,
    default: "15vh",
  },

  // 功能配置
  closeOnClickModal: {
    type: Boolean,
    default: true,
  },
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  showClose: {
    type: Boolean,
    default: true,
  },
  showFooter: {
    type: Boolean,
    default: true,
  },
  showCancelButton: {
    type: Boolean,
    default: true,
  },
  cancelButtonText: {
    type: String,
    default: "取消",
  },
  confirmButtonText: {
    type: String,
    default: "确认",
  },
  buttonSize: {
    type: String,
    default: "default",
  },
  draggable: Boolean,
  center: Boolean,
  modal: {
    type: Boolean,
    default: true,
  },
  appendToBody: {
    type: Boolean,
    default: true,
  },
  lockScroll: {
    type: Boolean,
    default: true,
  },
  destroyOnClose: Boolean,
  fullscreen: Boolean,

  // 状态控制
  loading: Boolean,
  loadingText: String,
  loadingIcon: {
    type: String,
    default: "Loading",
  },
  loadingIconSize: {
    type: Number,
    default: 24,
  },
  cancelLoading: Boolean,
  confirmLoading: Boolean,
  cancelDisabled: Boolean,
  confirmDisabled: Boolean,

  // 样式定制
  customClass: String,
  modalClass: String,
  bodyStyle: [String, Object],

  // 确认前校验
  beforeClose: Function,

  //动态样式
  baseDialog:String
});

const emit = defineEmits([
  "update:modelValue",
  "open",
  "opened",
  "close",
  "closed",
  "confirm",
  "cancel",
]);

const visible = ref(false);

// 监听modelValue变化
watch(
  () => props.modelValue,
  (val) => {
    visible.value = val;
  }
);

// 监听visible变化
watch(visible, (val) => {
  emit("update:modelValue", val);
});

// 计算尺寸对应的宽度
const dialogWidth = computed(() => {
  const sizeMap = {
    small: "400px",
    medium: "600px",
    large: "800px",
  };
  return props.width === "50%" ? sizeMap[props.size] : props.width;
});

// 处理打开事件
const handleOpen = () => {
  emit("open");
};

const handleOpened = () => {
  emit("opened");
};

// 处理关闭事件
const handleClose = (done) => {
  console.log("handleClose", done);

  if (typeof props.beforeClose === "function") {
    props.beforeClose(done);
  } else {
    emit("close");
    done();
  }
};

const handleClosed = () => {
  emit("closed");
};

// 按钮事件
const handleConfirm = () => {
  emit("confirm");
};

const handleCancel = () => {
  emit("cancel");
  visible.value = false;
};

// 暴露方法
defineExpose({
  open: () => {
    visible.value = true;
  },
  close: () => {
    visible.value = false;
  },
  toggle: () => {
    visible.value = !visible.value;
  },
});
</script>

<style lang="scss">
.base-dialog {
  margin-top:20px !important;
  // 基础样式
  :deep(.el-dialog) {
    border-radius: 12px !important;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.12);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    margin: 0;

    // 头部样式
    .el-dialog__header {
      padding: 16px 24px;
      margin-right: 0;
      border-bottom: 1px solid var(--el-border-color-light);
      background-color: var(--el-bg-color);

      .el-dialog__title {
        font-size: 18px;
        font-weight: 600;
        color: var(--el-text-color-primary);
      }

      .el-dialog__headerbtn {
        top: 16px;
        right: 24px;

        .el-dialog__close {
          color: var(--el-text-color-secondary);
          font-size: 20px;

          &:hover {
            color: var(--el-text-color-primary);
          }
        }
      }
    }

    // 内容区域
    .el-dialog__body {
      padding: 24px;
      flex: 1;
      overflow: auto;

      .dialog-body {
        min-height: 60px;

        .loading-container {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          height: 120px;

          .loading-icon {
            margin-bottom: 12px;
            animation: rotating 2s linear infinite;
          }

          .loading-text {
            color: var(--el-text-color-secondary);
            font-size: 14px;
          }
        }
      }
    }

    // 底部区域
    .el-dialog__footer {
      padding: 16px 24px;
      border-top: 1px solid var(--el-border-color-light);
      background-color: var(--el-bg-color);

      .default-footer {
        display: flex;
        justify-content: flex-end;
        gap: 12px;
      }
    }
  }

  // 尺寸变体
  &.small {
    :deep(.el-dialog) {
      max-width: 400px;
    }
  }

  &.medium {
    :deep(.el-dialog) {
      max-width: 600px;
    }
  }

  &.large {
    :deep(.el-dialog) {
      max-width: 800px;
    }
  }
}

@keyframes rotating {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
